
lib3ddevil1/bindings
Python interface to C library functions of lib3ddevil1.

This component uses ctypes thus it must access a compiled .so file (internally 
a .dll for Windows). The .so may be located in the top level of the library 
directory or any directory in the environment variable's path.

Note that there are two categories of objects in each python interface. One is
derived from ctypes.Structure, and the other is a pythonic object. The former 
is for internal use and requires knowledge of both python, C, and ctypes. The 
latter is to be used by python users.

Functions and Objects
    class pyPldHeader
        def __init__(self, filedata = None):
            parameters: file data, is a single line list of data.
    
            This function may raise RuntimeError when it fails to initialize
            based on file data.

        def show(self):
            This prints the contents of the object.

        def getnumoffsets(self):
            This returns the attribute numOffsets of a PldHeader.
            See details of the C struct in doc-pld.txt.

        def getoffsets(self):
            This returns a pythonic list of offsets.
            The offsets can be accessed via list comprehensions.

        def sizeofsector(self, i):
            parameter: i, an integer.
            This returns the size of the i-th sector in the .pld.

            If the result is -1, then specified i is out of range.

    class PyTexturePack
        def __init__(self, filedata):
            parameters: file data, a single line list of data.

            This function may raise RuntimeError when it fails to initialize
            based on file data.

            See details of the C struct in doc-tex.txt.

            def show(self):
                This prints the contents of the object.

            def getbatchnumber(self):
                This returns the attribute 'batchNumber'.

            def getfirstbatchoffset(self):
                This returns the attribute 'firstBatchOffset'.

    class pyTextureBatchDescriptor:
        def __init__(self, i, filedata):
            parameters: i, for i-th instance of TextureBatchDescriptor.
                        filedata, a single line list of data.

            This function may raise RuntimeError when it fails to initialize 
            based on file data.

            See details of the C struct in doc-tex.txt.

        def show(self):
            This prints the contents of the object.

        def getbatchidx(self):
            This returns the attribute 'batchidx'.

        def gethash(self):
            This returns the attribute 'hash'.

        def gettexnumber(self):
            This returns the attribute 'texNumber'.

        def gettexturesize(self):
            This returns the attribute 'textureSize'.

    class pyTextureBatch:
        def __init__(self, i, filedata):
            parameters: i, for i-th instance of TextureBatch.
                        file data, a single line list of data.

            This function may raise RuntimeError when it fails to initialize 
            based on file data.

            See details of the C struct in doc-tex.txt.
                        
        def gettextures(self):
            This returns a pythonic list of texture data.
            The textures can be accessed via list comprehensions.

    class pyGeoHeader:
        def __init__(self, filedata):
            parameters: file data, a single line list of data.

            This function may raise RuntimeError when it fails to initialize
            based on file data.

            See details of the C struct in doc-geo.txt.

        def show(self):
            This prints the contents of the object.

        def getnummesh(self):
            This returns the attribute 'numMesh'.

        def getunknownb(self):
            This returns the attribute 'unknownNumberB'.

        def getunknownc(self):
            This returns the attribute 'unknownNumberC'.

        def getunknownd(self):
            This returns the attribute 'unknownNumberD'.

        def getpadding(self):
            This returns the attribute 'padding'.

        def getunknownoffset(self):
            This returns the attribute 'unknownOffset'.

    class pyMeshHeader:
        def __init__(self, i, filedata):

        def show(self):
            This prints the contents of the object.

        def getnumbatch(self):
            This returns the attribute 'numBatch'.

        def getnumvertex(self):
            This returns the attribute 'numVertex'.

        def getunknown(self):
            This returns the attribute 'u'.

        def getoffsetbatches(self):
            This returns the attribute 'offsetBatches'.

        def getflags(self):
            This returns the attribute 'flags'.

    class pyMesh:
        def __init__(self, i, filedata):
            parameters: i, for i-th instance of Mesh.
                        filedata, a single line list of data.

            This function may raise RuntimeError when it fails to initialize
            based on file data.

            See details of the C struct in doc-geo.txt.

        def show(self):
            This prints the contents of the object.

        def getbatchdata(self):
            This returns the attribute 'bd'.
            It is a object without methods, and it's attributes are 
            conventionally accessed with the '.' operator.

        def getpositions(self):
            This returns a pythonic list of 'positions'.
            The positions can be accessed with list comprehensions.

            A position is a object 'Coordinate' without methods.
            The attributes are x, y, and z to be accessed with the 
            '.' operator.

        def getnormals(self):
            This returns a pythonic list of 'normals'.
            The normals can be accessed with list comprehensions.

            A normal is a object 'Coordinate' without methods.
            The attributes are x, y, and z to be accessed with the 
            '.' operator.

        def getuvs(self):
            This returns a pythonic list of 'u'.
            The UVs can be accessed with list comprehensions.

            A UV has two attributes, 'u' and 'v'.
        
        def getboneindexes(self):
            This returns a pythonic list of 'bi'.
            The bone indices can be accessed with list comprehensions.

            A bone index is a fixed length array of 4 elements, unsigned byte.

        def getboneweights(self):
            This returns a pythonic list of 'bw'.
            The bone weights can be accessed with list comprehensions.

            A bone weight is effectively an integer in python.

Example Logic: Extract Pld's
    with open("pl01.pld", "rb") as f:
        data = f.read()
        pld = pyPldHeader(data)
        filename = "demonstrate"
        i = 0
        for offset in pld.getoffsets():
            with open(filename + str(i), "wb") as fw:
                end = offset + pld.sizeofsector(i)
                chunk = data[offset:end]
                fw.write(chunk)
            i += 1

Example Logic: Extract Textures from a Single Batch
    with open("pl01.pld_1.txp", "rb") as f:
        data = f.read()
        tp   = pyTexturePack(data)
        filename = "texture"    # part 1 of output file name
        id       = 0            # part 2 of output file name
        # Iterate through all of the batches in the package.
        for i in range(0, tp.getbatchnumber()):
            # Get a batch.
            tx = pyTextureBatch(i, data)
            # Iterate through all textures in batch.
            for texture in tx.gettextures():
                with open(filename + str(id) + ".dds", "wb") as fw:
                    fw.write(texture)
                id += 1

Example Logic: Iterate through all MeshHeaders and Meshes:
    with open("pl00.pld_0", "rb") as f:
        # Get data to extract from.
        data = f.read()
        # We want to know how many meshes are in the file.
        gh = pyGeoHeader(data)
        # Show each MeshHeader 
        for i in range(0, gh.getnummesh()):
            mh = pyMeshHeader(i, data)
            mh.show()
        # Get each Mesh
        for i in range(0, gh.getnummesh()):
            m = pyMesh(i, data)
            m.show()
            # Whatever you do with each of them is up to you.

